#ifndef _VERIFIED_MESSAGE_BASE_HPP
#define _VERIFIED_MESSAGE_BASE_HPP 1

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <boost/shared_ptr.hpp>

#include "../constants.hpp"

namespace BFT
{
	namespace messages
	{

		struct verifiedMessageBaseStruct
		{
		  uint16_t tag; //message tag
		  uint32_t size; //message size = tag+size+payload+auth = buffer_length
		  uint32_t payload_start; //index of the bytearray pointing to the start of the payload
		  uint32_t payload_size; //size of the payload
		  uint32_t authentication_start; //index of the bytearray pointing to the start of the authentication
		  uint32_t authentication_size; // size of the authentication
		};

		class VerifiedMessageBase 
		{

		public:
		  
		  VerifiedMessageBase(uint16_t _tag, uint32_t _size, uint32_t _auth_size);
		 
		  VerifiedMessageBase(boost::shared_ptr<char> _bits, int _buffer_length);

		  uint32_t getTotalSize(); //size of trhe actual message, markers excluded
		  
		  uint32_t getAuthenticationSize();
		  
		  bool equals(boost::shared_ptr<VerifiedMessageBase> _m);
		  
		//  bool matches(VerifiedMessageBase m);
		  
		//  bool isValid();
		  
		  boost::shared_ptr<char> getBytes(int& _buffer_length);
		  
		  boost::shared_ptr<char> getBytes();
		  
		  uint32_t getAuthenticationStartIndex();
		  
		  uint32_t getAuthenticationEndIndex();  
		  
		//  uint32_t getAuthenticationLength();
		  
		  uint16_t getTag();
		  
		  uint32_t getPayloadSize();
		  
		//  string* toString();
		  
		  static uint32_t getOffset();

		  void printInfo();
		  
		//  boost::shared_ptr<char> VerifiedMessageBase::buildNewBytes(int& _buffer_length); // builds a new vmb, testing purpose only
		  
		protected:

		//  int verificationBaseSize();

		  boost::shared_ptr<char> buffer;
		  int buffer_length;
		  verifiedMessageBaseStruct info;
		  
		  VerifiedMessageBase();
		  
		private:
		
		//virtual void useless(){};
  
		  
		};



		inline uint32_t VerifiedMessageBase::getAuthenticationSize() {return info.authentication_size;}

		inline uint32_t VerifiedMessageBase::getAuthenticationStartIndex() {return info.authentication_start;}

		inline uint32_t VerifiedMessageBase::getAuthenticationEndIndex() {return info.authentication_start + info.authentication_size;}

		inline uint32_t VerifiedMessageBase::getOffset() {return TAG_SIZE + SIZE_SIZE;}

		inline uint16_t VerifiedMessageBase::getTag() {return info.tag;}
		

	} //namespace messages
} // namespace BFT

#endif
